<?php

namespace app\index\controller;

use app\api\service\DmjUserService;
use app\BaseController;
use app\common\model\Mobile;
use app\common\service\system\think\Image;
use Endroid\QrCode\Color\Color;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelLow;
use Endroid\QrCode\Label\Label;
use Endroid\QrCode\Label\Margin\Margin;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin;
use Endroid\QrCode\Writer\PngWriter;
use think\facade\Db;
use think\facade\View;
use think\Request;
use app\common\model\OilCard;
use app\common\model\Power;
use app\common\model\Export;
use think\Response;
use app\api\model\CouponOrder;

class Index extends BaseController
{
    public function oilAuth(Request $request)
    {
        $param = $request->only(['auth_code' => '', 'redirect_url' => '']);
        if (!$param['auth_code']) {
            return '无效认证';
        }
        if (!$param['redirect_url']) {
            return '无效跳转地址';
        }

        $user = invoke(DmjUserService::class)->byCode($request->param('auth_code'));
        if ($user['code']) {
            return '<a href="' . $param['redirect_url'] . '">认证失败，点击继续跳转</a>';
        }
        session('dmjuser', $user['data']);

        header('Location:' . $param['redirect_url']);
        exit;
    }

    public function index()
    {
        header('Location: /agent');
    }

    /**
     * gitee Web 钩子.
     *
     * 推送地址：http[s]://xxxx/index/index/webhook
     */
    public function webhook()
    {
        if ($this->request->isPost()) {
            $giteeToken = $this->request->header('X-Gitee-Token');
            $timestamp = $this->request->header('X-Gitee-Timestamp');
            $secret = 'kdkg21%(skdj!@KLS9e4029';
            $token = base64_encode(hash_hmac('sha256', $timestamp . "\n" . $secret, $secret, true));
            if ($token !== $giteeToken) {
                exit('Oh, no no no...');
            }

            // $target = Env::get('root_path');
            // $target = root_path();
            $payload = input('post.');
            // $target = '/www/wwwroot/'.$payload['repository']['name'];
            $target = '/www/wwwroot/api-dev-3'; // 测试环境自动更新

            $cmd = "cd $target && sudo -Huwww git pull";
            shell_exec($cmd);

            echo 'Yes';
        }
    }

    public function nianyu()
    {
        $info = Db::name('mobile_supplier')
            ->field('id, app_id, app_secret, url')
            ->where('code', 'nianyu')
            ->where('is_deleted', 0)
            ->find();

        if (empty($info)) {
            echo '账号异常';
            exit;
        }
        $model = new \api\Nianyu($info);
        $ispStatus = $model->getIspStatus();
        $successRate0 = $model->getSuccessRate(0);
        $successRate1 = $model->getSuccessRate(1);
        View::assign([
            'ispStatus' => $ispStatus,
            'successRate0' => $successRate0,
            'successRate1' => $successRate1,
        ]);

        return View::fetch();
    }

    /**
     * 测试环境话费订单随机成功或者失败
     */
    public function testOrder()
    {
        if (isProd()) {
            exit;
        }

        $list = Db::name('mobile_order')
            ->where('status', 2)
            ->whereIn('supplier_status', [1, 2])
            ->limit(300)
            ->select()
            ->toArray();
        $success = 0;
        $fail = 0;
        foreach ($list as $order) {
            $supplierStatus = mt_rand(3, 4);
            $update = [
                'supplier_order_no' => time(),
                'supplier_status' => $supplierStatus,
                'finish_time' => time(),
            ];
            if ($supplierStatus == 4) {
                // $update['refund_status'] = 2;
                $update['supplier_status'] = 99;
                $supplierStatus = 99;
                $fail += 1;
            } else {
                $success += 1;
            }

            try {
                if ($supplierStatus == 3 && $order['settle_type'] == SETTLE_TYPE_PROFIT) {
                    if ($order['profit'] == 0) {
                        $update['settle_status'] = 3;
                    } elseif ($order['settle_status'] == 1) {
                        $update['settle_status'] = 2;
                    }
                }
                Mobile::handleNotify($order, $update);
            } catch (\Exception $e) {
                Db::rollback();
                echo $e->getMessage() . PHP_EOL;
            }
        }
        echo '成功 ' . $success . ' 失败 ' . $fail;
    }

    /**
     * 测试环境油卡订单随机成功或者失败
     */
    public function testOilCardOrder()
    {
        exit;
        if (isProd()) {
            exit;
        }

        $list = Db::name('oil_card_order')
            ->where('status', 2)
            ->where('supplier_status', 1)
            ->limit(300)
            ->select()
            ->toArray();
        $success = 0;
        $fail = 0;
        foreach ($list as $order) {
            $supplierStatus = mt_rand(3, 4);
            $update = [
                'supplier_order_no' => time(),
                'supplier_status' => $supplierStatus,
                'finish_time' => time(),
            ];
            if ($supplierStatus == 4) {
                $update['refund_status'] = 2;
                $fail += 1;
            } else {
                $success += 1;
            }

            try {
                if ($supplierStatus == 3 && $order['settle_type'] == SETTLE_TYPE_PROFIT) {
                    if ($order['profit'] == 0) {
                        $update['settle_status'] = 3;
                    } elseif ($order['settle_status'] == 1) {
                        $update['settle_status'] = 2;
                    }
                }
                OilCard::handleNotify($order, $update);
            } catch (\Exception $e) {
                Db::rollback();
                echo $e->getMessage() . PHP_EOL;
            }
        }
        echo '成功 ' . $success . ' 失败 ' . $fail;
    }

    /**
     * 测试环境电费订单随机成功或者失败
     */
    public function testPowerOrder()
    {
        exit;
        if (isProd()) {
            exit;
        }

        $list = Db::name('power_order')
            ->where('status', 2)
            ->where('supplier_status', 1)
            ->limit(300)
            ->select()
            ->toArray();
        $success = 0;
        $fail = 0;
        foreach ($list as $order) {
            $supplierStatus = mt_rand(3, 4);
            $update = [
                'supplier_order_no' => time(),
                'supplier_status' => $supplierStatus,
                'finish_time' => time(),
            ];
            if ($supplierStatus == 4) {
                $update['refund_status'] = 2;
                $fail += 1;
            } else {
                $success += 1;
            }

            try {
                if ($supplierStatus == 3 && $order['settle_type'] == SETTLE_TYPE_PROFIT) {
                    if ($order['profit'] == 0) {
                        $update['settle_status'] = 3;
                    } elseif ($order['settle_status'] == 1) {
                        $update['settle_status'] = 2;
                    }
                }
                Power::handleNotify($order, $update);
            } catch (\Exception $e) {
                Db::rollback();
                echo $e->getMessage() . PHP_EOL;
            }
        }
        echo '成功 ' . $success . ' 失败 ' . $fail;
    }

    /**
     * 获取请求参数
     */
    public function getSign()
    {
        if (isProd()) {
            exit;
        }

        $data = input('post.');
        if (empty($data['app_key'])) {
            return fail('缺少参数 app_key');
        }
        $appSecret = Db::name('agent')
            ->where('app_key', $data['app_key'])
            ->value('app_secret');
        if (empty($appSecret)) {
            return fail('账号不存在');
        }
        $data['timestamp'] = time();
        $data['sign'] = getSign($data, $appSecret);
        return json($data, 200);
    }

    /**
     * 守兔影票模拟订单回调
     */
    public function taototoNotify(Request $request)
    {
        if (isProd()) {
            exit;
        }

        $data = input('');
        if (empty($data['order_id'])) {
            exit('订单号不能为空');
        }
        if (empty($data['status'])) {
            exit('状态不能为空');
        }
        $order = Db::name('movie_order')
            ->where('order_id', $data['order_id'])
            ->find();
        if (empty($order)) {
            exit('订单不存在');
        }

        if (in_array($order['supplier_status'], [4, 10])) {
            exit('该订单处理过了，别乱来啊');
        }

        switch ($data['status']) {
            case 4: // 已出票
                $params = [
                    'thirdOrderId' => $order['order_id'],
                    'eventName' => 'TICKET_SUCCESS',
                    'realSeat' => $order['seats_str'],
                    'ticketCode' => json_encode([mt_rand(0, 9999)]),
                    'ticketImage' => json_encode([
                        "http://shoutudyp.oss-cn-shenzhen.aliyuncs.com/c4bb88ba37fdbd94fdc66876e6307085.png",
                    ]),
                ];
                break;
            case 10: // 出票失败
                $params = [
                    'thirdOrderId' => $order['order_id'],
                    'eventName' => 'ORDER_CLOSE',
                    'closeCause' => '测试环境模拟出票失败',
                ];
                break;
            default:
                exit('状态有误');
        }

        $taototo = new \app\common\service\Taototo;
        $notifyUrl = $request->domain() . '/api/notify_v2/taototo';

        // 如果是出票成功，先回调竞价结算
        if ($data['status'] == 4) {
            $waitTicketParams = $taototo->getFormatParams([
                'thirdOrderId' => $order['order_id'],
                'eventName' => 'WAIT_TICKET',
                'orderPrice' => mt_rand(1, $order['sale_price'] / 2),
            ]);
            $res = curlPost($notifyUrl, json_encode($waitTicketParams), [
                'Content-Type: application/json; charset=utf-8',
            ]);
            $res = json_decode($res, true);
            if ($res['code'] != 200) {
                echo json_encode($res, JSON_UNESCAPED_UNICODE);
                exit;
            }
        }

        $params = $taototo->getFormatParams($params);
        $res = curlPost($notifyUrl, json_encode($params), [
            'Content-Type: application/json; charset=utf-8',
        ]);
        echo $res;
    }

    public function movieNotify()
    {
        echo 'success';
    }

    /**
     * 列表.
     */
    public function exportMobileOrder()
    {
        exit;
        $lastId = input('id', 0);
        $where = [];
        $where[] = ['id', '>', $lastId];
        $where[] = ['supplier_status', '=', 3];
        // 供应商
        $supplierList = Db::name('mobile_supplier')
            ->field('id, name')
            ->where('is_deleted', 0)
            ->select()
            ->toArray();
        $supplier = array_column($supplierList, 'name', 'id');

        $list = Db::name('mobile_order')
            ->where($where)
            ->limit(30000)
            ->order('id asc')
            ->select()
            ->toArray();
        // 返回导出excel 需要的数据
        $agentIds = array_column($list, 'agent_id');
        // 代理商
        $agent = Db::name('agent')
            ->whereIn('id', $agentIds)
            ->order('username asc')
            ->column('username, company_name', 'id');
        $res = [];
        $title = [
            'id', '供应商订单号', '系统订单号', 'API接口订单号', '供应商', '代理商用户名', '代理商公司名称',
            '销售价', '结算价', '成本价', '代理商利润', '平台利润', '充值号码', '充值金额', '运营商', '充值类型',
            '充值状态', '下单时间', '完成时间', '备注'
        ];
        $statusMap = [
            3 => '充值成功',
            4 => '充值失败',
        ];
        $ispTypeMap = [
            1 => '移动',
            2 => '联通',
            3 => '电信',
            -1 => '未知',
        ];
        foreach ($list as $v) {
            $ispType = getMobileIsp($v['mobile']);
            if ($v['finish_time']) {
                $v['finish_time'] = date('Y-m-d H:i:s', $v['finish_time']);
            } else {
                $v['finish_time'] = '';
            }
            $res[] = [
                $v['id'],
                $v['supplier_order_no'] . "\t",
                $v['sub_order_id'] . "\t",
                $v['out_order_id'] . "\t",
                $supplier[$v['mobile_supplier_id']] ?? '',
                $agent[$v['agent_id']]['username'],
                $agent[$v['agent_id']]['company_name'],
                fen2yuan($v['sale_price']) . '',
                fen2yuan($v['settle_price']) . '',
                fen2yuan($v['supplier_price']) . '',
                fen2yuan($v['profit']) . '',
                fen2yuan($v['platform_profit']) . '',
                $v['mobile'],
                fen2yuan($v['amount']),
                $ispTypeMap[$ispType],
                $v['order_type'] == 1 ? '慢充' : '快充',
                $statusMap[$v['supplier_status']] ?? '充值中',
                $v['created_at'],
                $v['finish_time'],
                $v['remark'],
            ];
        }
        unset($list);
        $export = new Export;
        $name = '话费订单';
        return $export->downloadExcel($title, $res, $name);
    }

    /**
     * 测试环境话费订单成功或者失败
     */
    public function mobileOrderUpdate()
    {
        if (isProd()) {
            exit;
        }

        $sub_order_id = input('order_id', '');
        $status = input('status', 0);
        if (empty($sub_order_id)) {
            echo '订单号要给啊';
            exit;
        }
        if (!in_array($status, [0, 1])) {
            echo 'status = 0，失败<br>status = 1，成功';
            exit;
        }

        $order = Db::name('mobile_order')
            // ->where('status', 2)
            ->where('sub_order_id', $sub_order_id)
            ->whereIn('supplier_status', [1, 2])
            ->find();
        if (empty($order)) {
            echo '订单号没找到，订单号你乱找的吗？<br>如果订单号不是乱找的话，确定下 supplier_status 是不是 1 或者 2';
            exit;
        }
        $update = [
            'supplier_order_no' => time(),
            'supplier_status' => $status == 0 ? 99 : 3,
            'finish_time' => time(),
        ];

        try {
            if ($status == 1 && $order['settle_type'] == SETTLE_TYPE_PROFIT) {
                if ($order['profit'] == 0) {
                    $update['settle_status'] = 3;
                } elseif ($order['settle_status'] == 1) {
                    $update['settle_status'] = 2;
                }
            }
            Mobile::handleNotify($order, $update);
        } catch (\Exception $e) {
            Db::rollback();
            echo $e->getMessage() . PHP_EOL;
            exit;
        }

        echo '你应该成功了';
    }


    public function qr()
    {

        $code = input('code');
        $is_show_code = input('isShowCode', CouponOrder::IS_SHOW_CODE);

        $writer = new PngWriter();

        $qrCode = QrCode::create($code)
            ->setEncoding(new Encoding('UTF-8'))
            ->setErrorCorrectionLevel(new ErrorCorrectionLevelLow())
            ->setSize(500)
            ->setMargin(10)
            ->setRoundBlockSizeMode(new RoundBlockSizeModeMargin())
            ->setForegroundColor(new Color(0, 0, 0))
            ->setBackgroundColor(new Color(255, 255, 255));
        $label = null;
        if ($is_show_code == CouponOrder::IS_SHOW_CODE) {
            $label = Label::create($code)
                ->setMargin(new Margin(20, 0, 20, 0))
                ->setTextColor(new Color(0, 0, 0));
        }
        $result = $writer->write($qrCode, null, $label);
        $content =   $result->getString();
        $res = Response::create($content,Image::class);
        return $res;


    }
}
